Categories
Fastify

Server-Side Development with Fastify — App Hooks

Spread the love

Fastify is a small Node framework for developing back end web apps.

In this article, we’ll look at how to create back end apps with Fastify.

Respond to a Request from a Hook

We can send responses from hooks.

For example, we can write:

const fastify = require('fastify')({})

fastify.addHook('onRequest', (request, reply, done) => {
  reply.send('Early response')
})

const start = async () => {
  try {
    fastify.get('/', function (request, reply) {
      reply.send('some-text')
    })
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We call reply.send in the onRequest hook, so we see:

Early response

in the response.

Also, we can write:

const fastify = require('fastify')({})

fastify.addHook('preHandler', async (request, reply) => {
  reply.send('Early response')
  return reply
})

const start = async () => {
  try {
    fastify.get('/', function (request, reply) {
      reply.send('some-text')
    })
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

to get the same result with an async function.

Application Hooks

Fastify gs 4 application hooks. They are:

  • onReady — runs the server starts listening to requests
  • onClose — runs when fastify.close() is run to stop the server
  • onRoute — runs when a route is registered
  • onRegister — runs when a new plugin is registered and new encapsulation context is created.

For example we can write:

const fastify = require('fastify')({})

fastify.addHook('onRoute', (routeOptions) => {
  console.log(routeOptions.method)
  console.log(routeOptions.schema)
  console.log(routeOptions.url)
  console.log(routeOptions.path)
  console.log(routeOptions.routePath)
  console.log(routeOptions.bodyLimit)
  console.log(routeOptions.logLevel)
  console.log(routeOptions.logSerializers)
  console.log(routeOptions.prefix)
})

const start = async () => {
  try {
    fastify.get('/', function(request, reply) {
      reply.send('some-text')
    })
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

to use the onRoute hook.

routeOptions has properties about the route.

method has the request method. url has the request URL.

path is the alias for url .

routePath is the URL of the route without the prefix.

bodyLimit has the max request size.

To use the onRegister hook, we write:

const fastify = require('fastify')({})

fastify.decorate('data', [])

fastify.register(async (instance, opts) => {
  instance.data.push('hello')
  console.log(instance.data)

instance.register(async (instance, opts) => {
    instance.data.push('world')
    console.log(instance.data)
  }, { prefix: '/hola' })
}, { prefix: '/ciao' })

fastify.register(async (instance, opts) => {
  console.log(instance.data)
  console.log(opts.prefix)
}, { prefix: '/hello' })

fastify.addHook('onRegister', (instance, opts) => {
  instance.data = instance.data.slice()
  console.log(opts.prefix)
})

const start = async () => {
  try {
    fastify.get('/', function(request, reply) {
      reply.send('some-text')
    })
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We call instance.data.push to add data we use in the plugin.

opts.prefix has the prefix property from the 2nd argument.

Hook Scope

Hooks have their own scope.

We can access it with the this object.

For instance, we can write:

const fastify = require('fastify')({})

fastify.decorate('foo', 'bar')

fastify.addHook('onRequest', function (request, reply, done) {
  const self = this
  console.log(self.foo)
  done()
})

const start = async () => {
  try {
    fastify.get('/', function(request, reply) {
      reply.send('some-text')
    })
    await fastify.listen(3000, '0.0.0.0')
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

We call fastify.decorate to add properties to this in the onRequest hook.

The first argument is the property name and the 2nd is the value.

So self.foo should be 'bar' .

Conclusion

We can add hooks to our Fastify app to run code at various parts of the app’s lifecycle.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *